﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Security;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.InteropServices;

namespace netdom
{
    [Serializable]
    public partial class Form1 : Form
    {
        private List<string> oldComputers = new List<string>();
        private List<string> newComputers = new List<string>();
        //possibly replaceable by a dictionary
        private Dictionary<string,string> computers = new Dictionary<string, string>();
        //private string userName = System.Net.CredentialCache.DefaultNetworkCredentials.UserName;
        //private SecureString password = System.Net.CredentialCache.DefaultNetworkCredentials.SecurePassword;
        private string userName;
        private SecureString password;
        Process netdomProcess;
        //private string path;
        
        public Form1()
        {
            InitializeComponent();
            openCompNameFile();
            newComputerName.KeyPress += new KeyPressEventHandler(newComputerName_KeyPress);
        }

        void newComputerName_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (oldComputerName.Text != null)
            {
                if (e.KeyChar == (char)Keys.Enter)
                {
                    //add_Click_1(sender, e);
                    oldComputerName.Enabled = true;
                    add_Click_1(sender, e);
                    e.Handled = true;

                }
                
            }

            if (e.KeyChar == (char)Keys.Down)
            {
                oldNames.Focus();
                if (oldNames.SelectedIndex < oldNames.Items.Count - 1)
                {
                    oldNames.SelectedIndex++;
                }
            }
        }


        private void openCompNameFile()
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "Text Files (*.txt) | *.txt|All files (*.*)|*.*";
            DialogResult result = MessageBox.Show("Do you have a .txt file of computer names?", "Attention", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (result == DialogResult.Yes)
            {
                DialogResult openResult = openFileDialog1.ShowDialog();
                if (openResult == DialogResult.OK)
                    readInComputerNames(openFileDialog1.FileName);
            }
        }

        private void readInComputerNames(string fileName)
        {
            string computerNames;
            try
            {
                using (StreamReader reader = new StreamReader(fileName))
                {
                    while (!reader.EndOfStream)
                    {
                        computerNames = (reader.ReadLine());
                        computers.Add(computerNames, null);
                    }


                }
                //UpdateListBoxes();
            }
            catch (ArgumentException ex)
            {
                MessageBox.Show("Invalid file. Please select a text file with computer names\r\n" + ex.Message, "Unable to open file");

            }
            UpdateListBoxes();
        }

        private void UpdateListBoxes()
        {

            oldNames.Items.Clear();
            newNames.Items.Clear();
            oldNames.Focus();

                //for (int i = 0; i < computers.Keys.Count; i++)
                //{
                //    if (numberOfNotNullElements(computers.Keys) == numberOfNotNullElements(computers.Values))
                //    {
                //        //oldNames.Items.Add(number + "." + oldComputers[i]);
                //        oldNames.Items.Add(computers.Keys.ElementAt(i));
                //        //newNames.Items.Add(newComputers[i]);
                //        newNames.Items.Add(computers[computers.Keys.ElementAt(i)]);
                //    }
                //    if (numberOfNotNullElements(computers.Values) == 0)
                //        oldNames.Items.Add(computers.Keys.ElementAt(i));
            // old code for when I used two lists

            foreach (var pair in computers)
            {
                if (pair.Value != null && pair.Key != null)
                {
                    oldNames.Items.Add(pair.Key);
                    newNames.Items.Add(pair.Value);
                }
                else if (pair.Key == null)
                {
                    oldNames.Items.Add("No name specified");
                    newNames.Items.Add(pair.Value);
                }

                else if (pair.Value == null)
                {
                    oldNames.Items.Add(pair.Key);
                    newNames.Items.Add("No name specified");
                }
            }
            // the numbering was removed because it made things difficult with the dictionary and reading from files
        }

        private int numberOfNotNullElements(Dictionary<string, string>.ValueCollection valueCollection)
        {
            int number=0;
            foreach (string element in valueCollection)
            {
                if (element != null)
                {
                    number++;
                }
            }
            return number;
        }

        private int numberOfNotNullElements(Dictionary<string, string>.KeyCollection keyCollection)
        {
            int number=0;
            foreach (string element in keyCollection)
            {
                if (element != null)
                {
                    number++;
                }
            }
            return number;
        }



        private void rename_Click(object sender, EventArgs e)
        {
            Form2 passwordWindow = new Form2(this);
            passwordWindow.ShowDialog();
            while (passwordWindow.Visible)
                this.Enabled = false;
            ProcessStartInfo netdom = new ProcessStartInfo(@"C:\Windows\System32\netdom.exe");
            netdom.RedirectStandardInput = true;
            netdom.RedirectStandardOutput = true;
            netdom.WindowStyle = ProcessWindowStyle.Hidden;
            netdom.UseShellExecute = false;
            //Process netdomProcess;
            if (numberOfNotNullElements(computers.Keys) == numberOfNotNullElements(computers.Values))
            {
                foreach (string oldComputer in computers.Keys)
                {
                    netdom.Arguments = getArgument(oldComputer,computers[oldComputer]);
                    netdomProcess = Process.Start(netdom);
                    netdomProcess.WaitForExit();
                    if (netdomProcess.HasExited)
                    {
                        using (StreamReader myOutput2 = netdomProcess.StandardOutput)
                        {
                            string output = myOutput2.ReadToEnd();
                            textBox3.Text += "--- Renaming " + oldComputer + " to" + computers.Values + "---";
                            textBox3.Text += output;
                            textBox3.Text += DateTime.Now.ToLongTimeString();
                            textBox3.Text += "\r\n";
                            textBox3.Text += "\r\n";
                        }
                    }
                }
            }
            netdomProcess.Dispose();
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            fbd.ShowDialog();
            using (TextWriter tw = new StreamWriter(fbd.SelectedPath + "log.txt"))
            {
                tw.Write(textBox3.Text);
            }
        }

        private string ConvertSecureStringToString(SecureString input)
        {
            string output = "";
            IntPtr ptr = SecureStringToBSTR(input);
            output = PtrToStringBSTR(ptr);
            return output;
        }

        private IntPtr SecureStringToBSTR(SecureString ss)
        {
            IntPtr ptr = new IntPtr();
            ptr = Marshal.SecureStringToBSTR(ss);
            return ptr;
        }

        private string PtrToStringBSTR(IntPtr ptr)
        {
            string s = Marshal.PtrToStringBSTR(ptr);
            Marshal.ZeroFreeBSTR(ptr);
            return s;
        }
        public void setUserNameAndPassword(string userName, SecureString password)
        {
            this.userName = userName;
            this.password = password;
        }

        private string getArgument(string oldComputer, string newComputer)
        {
            string argument = "";
            argument += "RENAMECOMPUTER " + oldComputer + " /newname:" + newComputer + " /userd:" + userName + " /passwordd:" +ConvertSecureStringToString(password)+ " /force";
            //MessageBox.Show(argument);
            return argument;
        }


        private void delete_Click(object sender, EventArgs e)
        {
            if (numberOfNotNullElements(computers.Keys) != 0)
            {
                computers.Remove(oldNames.SelectedItem.ToString());
                UpdateListBoxes();
            }
            // watch out. I don't like that last line
        }

        private void openToolStripButton_Click(object sender, EventArgs e)
        {
            Dictionary<string, string> currentDictionary = computers;
            //make a backup

            OpenFileDialog openFileDialog2 = new OpenFileDialog();
            openFileDialog2.Filter = "Text Files (*.txt) | *.txt|All files (*.*)|*.*";
            openFileDialog2.CheckPathExists = true;
            openFileDialog2.CheckFileExists = true;

            DialogResult openResult = openFileDialog2.ShowDialog();
            if (openResult == DialogResult.OK)
                 //readInComputerNames(openFileDialog2.FileName);
                try
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    using (Stream input = File.OpenRead(openFileDialog2.FileName))
                    {
                        computers = (Dictionary<string, string>)bf.Deserialize(input);
                        UpdateListBoxes();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Something went wrong\r\n" + ex.Message);
                }
        }

        private void saveToolStripButton_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveDialog = new SaveFileDialog();
            saveDialog.Filter = "Text files (*.txt)|*.txt";
            saveDialog.CheckPathExists = true;
            saveDialog.Title = "Choose a file to save the current list of computers";
            if (saveDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                //    using (StreamWriter writer = new StreamWriter(saveDialog.FileName))
                //    {
                //        if (numberOfNotNullElements(computers.Values) != 0)
                //        {
                //            writer.WriteLine("Old Computer Names");
                //            writer.WriteLine();

                //            foreach (string key in computers.Keys)
                //            {
                //                writer.WriteLine(key);

                //            }

                //            writer.WriteLine();
                //            writer.WriteLine("New Computer Names");
                //            writer.WriteLine();

                //            foreach (string key in computers.Keys)
                //                writer.WriteLine(computers[key]);

                //        }
                //        else
                //        {
                //            writer.WriteLine("Old Computer Names");
                //            writer.WriteLine();
                //            foreach (string key in computers.Keys)
                //            {
                //                writer.WriteLine(key);

                //            }
                //        }
                //    }
                    BinaryFormatter bf = new BinaryFormatter();
                    using (Stream output = File.OpenWrite(saveDialog.FileName))
                    {
                        bf.Serialize(output, computers);
                    }
                }


                catch (ArgumentException ex)
                {
                    MessageBox.Show("Unable to save to file\r\n" + ex.Message, "Save Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void add_Click_1(object sender, EventArgs e)
        {
            if (newComputerName.TextLength > 15)
            {
                MessageBox.Show("New computer name too long!");
            }
            else
            {
                if (oldComputerName.Text == "" && oldNames.SelectedItem != null)
                {
                    //newComputers.Add(newComputerName.Text);
                    computers[oldNames.SelectedItem.ToString()] = newComputerName.Text;
                }
                else if (newComputerName.Text == "" && !computers.Keys.Contains<string>(oldComputerName.Text))
                {
                    //oldComputers.Add(oldComputerName.Text);
                    computers.Add(oldComputerName.Text, null);
                }
                else if (newComputerName.Text == "" && oldComputerName.Text == "")
                    return;

                else
                {
                    //oldComputers.Add(oldComputerName.Text);
                    //newComputers.Add(newComputerName.Text);
                    if ((!computers.Keys.Contains<string>(oldComputerName.Text)) && (!computers.Values.Contains<string>(newComputerName.Text)))
                        computers.Add(oldComputerName.Text, newComputerName.Text);

                    else if (computers.Keys.Contains<string>(oldComputerName.Text))
                        computers[oldComputerName.Text] = newComputerName.Text;
                }
            }

            UpdateListBoxes();
            newComputerName.Clear();
            oldComputerName.Clear();
            oldComputerName.Enabled = true;
            newComputerName.Enabled = true;
        }


        private void oldNames_SelectedIndexChanged(object sender, EventArgs e)
        {
            // this method just autofills the oldComputerName and newComputerName textboxes with whatever is selected in the listbox
            if (oldNames.SelectedItem == null || oldNames.SelectedItem.ToString() == "")
            {
                oldComputerName.Enabled = true;
            }

            else if (oldNames.SelectedItem != null)
            {
                oldComputerName.Text = oldNames.SelectedItem.ToString();

                if (computers[oldNames.SelectedItem.ToString()] != null)
                {
                    newComputerName.Text = computers[oldNames.SelectedItem.ToString()];
                }
                else
                {
                    string prefix;
                    prefix = oldComputerName.Text.Substring(0, 5);
                    newComputerName.Text = prefix;
                }

                oldComputerName.Enabled = false;
            }
        }
    }
}
